<template>
  <el-config-provider namespace="el">
    <div class="workflow-container">
      <section class="dingflow-design">
        <div class="zoom">
          <el-button circle :disabled="nowVal==50" @click="zoomSize(1)">
            <template #icon>
              <i-ep-minus />
            </template>
          </el-button>
          <span>{{ nowVal }}%</span>
          <el-button circle :disabled="nowVal==300" @click="zoomSize(2)">
            <template #icon>
              <i-ep-plus />
            </template>
          </el-button>
        </div>
        <div class="box-scale" :style="'transform: scale('+nowVal/100+'); transform-origin: 50% 0px 0px;'">
          <node-wrap v-model:node-config="nodeConfig" v-model:flow-permission="flowPermission" />
          <div class="end-node">
            <div class="end-node-circle" />
            <div class="end-node-text">流程结束</div>
          </div>
        </div>
      </section>
      <errorDialog
        v-model:visible="tipVisible"
        :list="tipList"
      />
      <promoter-drawer :tree-list="userList" :check-dept="checkDept" />
      <approver-drawer :tree-list="userList" :role-list="roleList" :types="approverTypes" />
      <copyer-drawer :tree-list="userList" />
      <condition-drawer :conditions="conditions" :tree-list="userList" :check-dept="checkDept" />
    </div>
  </el-config-provider>
</template>

<script>
import _ from 'lodash'
import { reactive, toRefs, computed, watch } from 'vue'
import { useStore } from 'vuex'
/**
 * nodeConfig 流程定义节点注释
 * --nodeName 节点名称
 * --type     节点类型 0发起人 1审批 2抄送 3条件 4路由
 * --priorityLevel 条件优先级
 * --settype  审批人设置 1指定成员 2主管 4发起人自选 5发起人自己 7连续多级主管
 * --selectMode   审批人数 1自选一个人 2自选多个人
 * --selectRange  审批选择范围 1全公司 2指定成员 2指定角色
 * --directorLevel  审批主管  最高层主管数
 * --superiorApproval 找不到主管时，由上级主管代审批
 * --examineMode  多人审批时采用的审批方式 1依次审批 2会签
 * --noHanderAction  审批人为空时 1自动通过 2自动驳回
 * --examineEndDirectorLevel  审批终点 第n层主管
 * --ccSelfSelectFlag  允许发起人自选抄送人
 * --conditionList  当审批单同时满足以下条件时进入此流程
 * --nodeUserList  操作人(1成员2部门3角色)
 * --childNode  子节点项
 * --conditionNodes 条件节点
 * --error  当前审批是否通过校验
 * conditionList: [{
    id: 'number27741',  表单组件id，不能更改
    type: 'number',  表单组件类型
    name: 'number27741', 表单组件唯一字段
    label: '天数',  表单组件标签
    value: 4,
    optType: '<'
  }]
  nodeUserList: [{
    id: 'user01',
    type: 1,  类型 1人员 2部门 3角色
    name: '张三'
  }]
 */
export default {
  name: 'AppWorkflow',
  props: {
    /** 表单数据 */
    widgetList: {
      type: Array,
      default: () => []
    },
    /** 用户部门列表 */
    userList: {
      type: Array,
      default: () => []
    },
    /** 角色列表 */
    roleList: {
      type: Array,
      default: () => []
    },
    /** 发起人允许选择部门 */
    checkDept: {
      type: Boolean,
      default: true
    },
    /** 流程设计数据 */
    processConfig: {
      type: Object,
      default: null
    },
    /** 保存事件 */
    onChange: {
      type: Function,
      default: null
    },
    /** 已作为条件项Ids */
    modelValue: {
      type: Array,
      default: () => []
    },
    /**
     * 审核类型
     * 1、指定成员
     * 2、主管
     * 4、发起人自选
     * 5、发起人自己
     * 7、连续多级主管
     */
    approverTypes: {
      type: Array,
      default: () => [1, 2, 4, 5, 7]
    }
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const store = useStore()
    const state = reactive({
      tipList: [], // 设置项检查
      tipVisible: false,
      nowVal: 100, // 缩放比例
      processConfig: {
        flowPermission: [],
        nodeConfig: {
          nodeName: '发起人',
          type: 0,
          conditionList: [],
          nodeUserList: []
        }
      },
      nodeConfig: {}, // 流程定义节点
      flowPermission: [] // 发起人范围
    })

    watch(props.processConfig, () => {
      _.merge(state.processConfig, props.processConfig)
      console.log('state.processConfig :>> ', state.processConfig)
    })

    const { nodeConfig, flowPermission } = state.processConfig
    state.nodeConfig = nodeConfig
    state.flowPermission = flowPermission

    /** 获取条件项 */
    const getConditionNodesIds = async(node, conditionNodes, value) => {
      const ids = value || []
      // 处理条件
      if (conditionNodes && conditionNodes.length > 0) {
        conditionNodes.forEach(e => {
          if (e.conditionList && e.conditionList.length > 0) {
            ids.push(...e.conditionList.map(m => m.name))
            return getConditionNodesIds(e.childNode, e.conditionNodes, ids)
          }
        })
      } else if (node) { // 处理子节点
        return getConditionNodesIds(node.childNode, node.conditionNodes, ids)
      }
      return ids
    }

    watch(nodeConfig, async(e) => {
      let ids = []
      ids = await getConditionNodesIds(e.childNode, e.conditionNodes)
      console.log('ids :>> ', ids)
      emit('update:modelValue', ids)
    })

    const widgetTypes = ['input', 'textarea', 'number', 'radio', 'checkbox', 'select']
    const conditions = computed(() => {
      return props.widgetList.filter(m => widgetTypes.includes(m.type) && m.options && m.options.required)
    })

    /** 缩放按钮事件 */
    const zoomSize = (type) => {
      if (type === 1) {
        if (state.nowVal === 50) {
          return
        }
        state.nowVal -= 10
      } else {
        if (state.nowVal === 300) {
          return
        }
        state.nowVal += 10
      }
    }

    /** 保存 */
    const setChange = () => {
      store.dispatch('app/workflow/setIsTried', true)
      state.tipList = []
      reErr(state.nodeConfig)
      if (state.tipList.length !== 0) {
        state.tipVisible = true
        return false
      }

      if (props.onChange) {
        props.onChange(state.processConfig)
      } else {
        return state.processConfig
      }
    }

    /** 设置项检查 */
    const reErr = ({ childNode }) => {
      if (childNode) {
        const { type, error, nodeName, conditionNodes } = childNode
        if (type === 1 || type === 2) {
          if (error) {
            state.tipList.push({ name: nodeName, type: ['', '审核人', '抄送人'][type] })
          }
          reErr(childNode)
        } else if (type === 3) {
          reErr(childNode)
        } else if (type === 4) {
          reErr(childNode)
          for (var i = 0; i < conditionNodes.length; i++) {
            if (conditionNodes[i].error) {
              state.tipList.push({ name: conditionNodes[i].nodeName, type: '条件' })
            }
            reErr(conditionNodes[i])
          }
        }
      } else {
        childNode = null
      }
    }

    return {
      ...toRefs(state),
      conditions,
      zoomSize,
      setChange
    }
  }
}
</script>

<style lang="scss" scoped>

.workflow-container {
  height: 100%;
  position: relative;
  background-color: var(--ep-color-info-light-9);

  .dingflow-design {
    width: 100%;
    overflow: auto;
    position: absolute;
    bottom: 0;
    left: 0;
    right: 0;
    top: 0;

    .box-scale {
      transform: scale(1);
      display: inline-block;
      position: relative;
      width: 100%;
      padding: 54.5px 0;
      align-items: flex-start;
      justify-content: center;
      flex-wrap: wrap;
      min-width: -webkit-min-content;
      min-width: -moz-min-content;
      min-width: min-content;
      transform-origin: 0 0 0;
    }

    .end-node {
      border-radius: 50%;
      font-size: 14px;
      color: var(--ep-color-info);
      text-align: left;
    }

    .end-node-circle {
      width: 10px;
      height: 10px;
      margin: auto;
      border-radius: 50%;
      background: var(--ep-color-info-light-5);
    }

    .end-node-text {
      margin-top: 5px;
      text-align: center;
    }
  }

  .zoom {
    display: flex;
    position: fixed;
    align-items: center;
    justify-content: space-between;
    width: 125px;
    right: 40px;
    margin-top: 30px;
    z-index: 10;

    span {
      font-size: 15px;
      color: var(--ep-color-info-dark-2);
    }
  }
}

</style>
